
Berta.Articles = new Class(function(){

	return {
		
		defaults: {},
		options: null,
		
		isOn: false,
		list: null,
		sectionId: null,
		
		constructor: function(options) {
			this.options = $.extend(true, {}, this.defaults, options);
			
			this.listContainer = $('.x-articles');
			
			var listContainerData = this.listContainer.data('berta');
			if(listContainerData && listContainerData.sectionId) {
				this.sectionId = listContainerData.sectionId;
			}
		},
		
		//   .______    __    __  .______    __       __    ______    ////////////////////////////////////////////////////////////
		//   |   _  \  |  |  |  | |   _  \  |  |     |  |  /      |   ////////////////////////////////////////////////////////////
		//   |  |_)  | |  |  |  | |  |_)  | |  |     |  | |  ,----'   ////////////////////////////////////////////////////////////
		//   |   ___/  |  |  |  | |   _  <  |  |     |  | |  |        ////////////////////////////////////////////////////////////
		//   |  |      |  `--'  | |  |_)  | |  `----.|  | |  `----.   ////////////////////////////////////////////////////////////
		//   | _|       \______/  |______/  |_______||__|  \______|   ////////////////////////////////////////////////////////////
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//  A P I   /////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		/**
		 * Turn on editing features for articles
		 */
		on:		/* API */ function() {
			this.isOn = true;
			this._(addControls)();
		},
		
		/**
		 * Turn off editing features
		 */
		off:	/* API */ function() {
			this.isOn = false;
			this._(removeControls)();
		},
		
		/**
		 * Create new article in the current section
		 * @param	function	Callback
		 */
		create:	/* API */ function(callback) {
			if(!callback) callback = null;
			Berta.Server.instance().post(Berta.Route.get('post:entries', null, { section_id: this.sectionId }), this._(createComplete, callback));
		},
		
		/**
		 * Delete article
		 * @param	misc		DOM element or article ID
		 * @param	function	Callback
		 */
		del:	/* API */ function(articleOrId, callback) {
			if(!callback) callback = null;
			
			var aId = this.getId(articleOrId);
			if (aId > 0) {
				Berta.Server.instance().del(Berta.Route.get('delete:entry', { 'id' : aId }), this._(deleteComplete, [aId, callback]));
			}
		},
		
		/**
		 * Reload article
		 * @param	misc		DOM element or article ID
		 * @param	function	Callback
		 */
		reload:	/* API */ function(articleOrId, callback) {
			if(!callback) callback = null;
			
			var aId = this.getId(articleOrId);
			if(aId > 0) {
				Berta.Server.instance().get(Berta.Route.get('get:snippet-entry-listed', { 'id' : aId }), this._(reloadComplete, [aId, callback]));
			}
		},
		
		/**
		 * Move article up one position
		 */
		moveUp: /* API */ function(articleOrId, callback) {
			if(!callback) callback = null;
			var aId = this.getId(articleOrId);
			if(aId > 0) {
				Berta.Server.instance().put(Berta.Route.get('put:entry-promote', { 'id' : aId }), this._(moveComplete, [aId, 'up', callback]));
			}
		},
		
		/**
		 * Move article down one position
		 */
		moveDown: /* API */ function(articleOrId, callback) {
			if(!callback) callback = null;
			var aId = this.getId(articleOrId);
			if(aId > 0) {
				Berta.Server.instance().put(Berta.Route.get('put:entry-demote', { 'id' : aId }), this._(moveComplete, [aId, 'down', callback]));
			}
		},
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		//  . . .   /////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		
		replaceWithNewHTML: function(article, newHTML) {
			var a = this.get(article);
			if(a !== false) {
				a.after(newHTML);
				this.removeFromDOM(a);
			} else {
				//$.log(this.listContainer, newHTML);
				this.listContainer.append(newHTML);
			}
			
			this._(addControls)();
		},
		
		removeFromDOM: function(article) {
			var a = this.get(article);
			if (a !== false) {
				Berta.EditorManager.instance().unregisterEditables(a.find('.x-editable'));
				a.empty().remove();
			}
		},
		
		get: function(articleOrId) {
			var a = false;
			if (typeof(articleOrId) == 'number' || typeof(articleOrId) == 'string') {
				this.listContainer.find('.x-article').each(function() {
					var articleData = $(this).data('berta');
					if (articleData && articleData.id == articleOrId) {
						a = $(this);

						return false;
					}
				});
			} else {
				a = $(articleOrId);
				if(a.length == 0) a = false;
			}
			
			return a;
		},
		getId: function(articleOrId) {
			var aId = false;
			if (typeof(articleOrId) == 'number' || typeof(articleOrId) == 'string') {
				aId = parseInt(articleOrId);
			} else {
				var articleData = $(articleOrId).data('berta');
				if(articleData && articleData.id) aId = articleData.id;
			}
			
			return aId;
		}
		
		
	};
	
	//   .______   .______     __  ____    ____  ___   .___________. _______    //////////////////////////////////////////////////
	//   |   _  \  |   _  \   |  | \   \  /   / /   \  |           ||   ____|   //////////////////////////////////////////////////
	//   |  |_)  | |  |_)  |  |  |  \   \/   / /  ^  \ `---|  |----`|  |__      //////////////////////////////////////////////////
	//   |   ___/  |      /   |  |   \      / /  /_\  \    |  |     |   __|     //////////////////////////////////////////////////
	//   |  |      |  |\  \--.|  |    \    / /  _____  \   |  |     |  |____    //////////////////////////////////////////////////
	//   | _|      | _| `.___||__|     \__/ /__/     \__\  |__|     |_______|   //////////////////////////////////////////////////

	function createComplete(callback, xhrId, response) {
		var newId;
		if(response.error) {
			alert(response.errorMessage);
			if(jQuery.isFunction(callback)) callback(newId);
		} else {
			newId = response.json.values.id;
			this.reload(newId, callback);
			// forward the callback to reload function, and call it only when reloading finishes
		}
	}
	function reloadComplete(id, callback, xhrId, response) {
		if(response) {
			this.replaceWithNewHTML(id, $(response.text));
 		} else {
			$.logWarn('Bad response from server (Articles::reloadComplete)');
		}
		if(jQuery.isFunction(callback)) callback(id);
	}
	function deleteComplete(id, callback, xhrId, response) {
		if(response.error) {
			alert(response.errorMessage);
		} else {
			this.removeFromDOM(id);
		}
		if(jQuery.isFunction(callback)) callback(id);
	}
	function moveComplete(id, direction, callback, xhrId, response) {
		if(response.error) {
			alert(response.errorMessage);
		} else {
			var a = this.get(id);
			var b = (direction == 'up') ? a.prev('.x-article') : a.next('.x-article');
			if (b.length > 0) {
				a.animate({'opacity': 0}, 250, function() {
					if(direction == 'up') {
						b.before(a);
					} else {
						b.after(a);
					}
					a.animate({'opacity': 1}, 550);
				});
			}
		}
		if(jQuery.isFunction(callback)) callback(id);
	}
	
	
	
	function onArticleDeleteClick(event) {
		var art = $(event.target).parents('.x-article');
		this.del(art);
		return false;
	}
	function onArticleUpClick(event) {
		var art = $(event.target).parents('.x-article');
		this.moveUp(art);
		return false;
	}
	function onArticleDownClick(event) {
		var art = $(event.target).parents('.x-article');
		this.moveDown(art);
		return false;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	function addControls() {
		var articlesAdded = false, self = this;
		this.listContainer.find('.x-article').each(function(idx, art) {
			art = $(art);
			if(!art.hasClass('x-article-controlled')) {
				art.prepend(self._(getControlsElements)(art));
				art.addClass('x-article-controlled');
				Berta.EditorManager.instance().registerEditables(art.add(art.find('.x-editable')), 'articles');
				articlesAdded = true;
			}
		});
		return articlesAdded;
	}
	function removeControls() {
		var articlesRemoved = false, self = this;
		this.listContainer.find('.x-article').each(function(idx, art) {
			art = $(art);
			if(art.hasClass('x-article-controlled')) {
				art.find('.x-article-controls:first').remove();
				art.removeClass('x-article-controlled');
				Berta.EditorManager.instance().unregisterEditables(art.find('.x-editable'));
				articlesRemoved = true;
			}
		});
		return articlesRemoved;
	}
	function getControlsElements(article) {
		var articleData = article.data('berta');
		var artId = articleData.id;
		var tags = articleData.tags;

		var cont = $('<div class="x-article-controls"></div>');
		cont.append(
			$('<div class="x-article-tags x-editable"></div>')
				.data({ 'berta' : {
					'editor': 'Textline',
					'route': 'put:entry',
					'route_variables': { 'id': artId },
					'variable': 'tags',
					'editor_params': { 'caption': 'Tags' }
				}})
				.html(tags)
			).append(
				$('<div class="x-control-dropdown"></div>').append($('<p />').append($('<a href="#" class="x-article-up">move up</a>').click(this._(onArticleUpClick))))
												   .append($('<p />').append($('<a href="#" class="x-article-down">move down</a>').click(this._(onArticleDownClick))))
												   .append($('<p />').append($('<a href="#" class="x-article-delete">delete</a>').click(this._(onArticleDeleteClick))))
			).append(
				$('<div class="x-control-move"></div>')
			);

		return cont;
	}
	


}());
